package com.pig4cloud.pigx.contract.executer.order.initializer;

import com.pig4cloud.pigx.common.customize.mysql.utils.MysqlUtil;
import com.pig4cloud.pigx.common.seata.utils.SeataUtils;
import com.pig4cloud.pigx.contract.bo.ContractOrderNewBO;
import com.pig4cloud.pigx.contract.constant.OrderExecutorErrorMsg;
import com.pig4cloud.pigx.contract.dto.ContractOrderNewDTO;
import com.pig4cloud.pigx.contract.mapstruct.ContractOrderStruct;
import com.pig4cloud.pigx.contract.vo.ContractOrderInitResVO;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

/**
 * 订单初始化器管理器
 *
 * @since 2022/8/17 13:43
 */
@Data
@Slf4j
@Component
public class OrderInitializerManager {

    /**
     * 订单初始化器集合
     */
    private final List<OrderInitializer> initializerList = new ArrayList<>();

    @Autowired
    private MysqlUtil mysqlUtil;

    /**
     * 订单初始化
     *
     * @param dto 入参
     * @return {@link ContractOrderInitResVO}
     * @since 2022/8/17 11:15
     */
    public ContractOrderInitResVO init(ContractOrderNewDTO dto) {
        // 转换类型
        ContractOrderNewBO bo = ContractOrderStruct.INSTANCE.orderNewDTO2OrderNewBO(dto);

        for (OrderInitializer i : initializerList) {
            try {
                if (!i.support(bo)) {
                    continue;
                }

                // 开启本地事务
                mysqlUtil.startLocalTx();

                i.init(bo);
                return i.success(bo);
            } catch (Exception e) {
                // 回滚分布式事务
                SeataUtils.rollbackGlobalTx();
                // 回滚本地事务
                mysqlUtil.rollbackLocalTx();

                i.fail(bo, e);
                log.error(OrderExecutorErrorMsg.ORDER_INIT_ERROR, e.getMessage());
                throw e;
            }
        }

        throw new RuntimeException(OrderExecutorErrorMsg.ORDER_INIT_NOT_MATCH);
    }
}
